#include"my_SeqList.h"


//1.顺序表初始化 (函数定义)

//结构体类型在创建时不能初始化，类型就不能初始化，在用类型创建出变量后对变量进行初始化
//创建的变量要初始化，初始化后的值在后面有要先赋值时也不会错，除非它有明确它后面全是用来接值的

//把顺序表初始化的函数的定义
void SLInit(SL* ps)//把创建的结构体变量的地址传过来
{
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
	//后面肯定要用它对它扩，刚开始置为0的后面用到时是对0的对象扩
}


//2.顺序表的销毁 (函数定义)

//去执行销毁顺序表时一定经过了增删查改顺序表不会创建顺序表接着就是执行销毁顺序表的，肯定执行了前面的，在前面有检查ps就行了
void SLDestory(SL* ps)//创建的结构体变量的地址一定非空的，顺序表结构体变量是自己创建的结构体变量一定存在，创建时里面的int*也一定非空的，接着也初始化为0了，只是后面不知道是否被置为空也安全地过来或者单纯是没打算建顺序表的过来的情况，此时就应该自然地略去销毁，而不是assert去报错，因为你前面都安全地过来了此时要应对的情况肯定就是本就没打算建表的情况，自然略去地销毁
{
	assert(ps);
	//传正常创建结构体变量的指针，指针一定非空的，这个断言也是防被人搞的，让代码健壮
	if (ps->arr)
	{
		free(ps->arr);//创建的顺序表数组内存的销毁，内存的释放
	}
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}


//3.顺序表里面存放数据数组内存的开辟
void SLMerBla(SL* ps)//所有调有它的之前都判断过ps，都是ps不等于空下涉及的它
{//每次插入顺序表前都要检查一下空间是否够要再开辟，保证插入时的空间都是足够的
	if (ps->size == ps->capacity)//顺序表数组里的有效数据元素个数总是小于等于顺序表数组的总大小，相等时就要再开辟更大空间继续放得下了
	{
		//若capacity为0，给个默认值，其它的都×2倍
		ps->capacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		SLDatatype* tmp = (SLDatatype*)realloc(ps->arr, ps->capacity * sizeof(SLDatatype));
		if (tmp == NULL)
		{
			perror("realloc fail!");
			exit(1);
		}
		ps->arr = tmp;
	}
}


//4.往顺序表数组尾部插入一个元素x (函数定义)
void SLPushBack(SL* ps, SLDatatype x)
{//传来的结构体变量指针地址肯定是有的，经过初始化后空的是结构体里面变量的内容是空，它本身不空
	assert(ps);//assert(ps != NULL) 判断为真，往下执行,判断为假，报错
	//or
	/*if (ps == NULL)
	{
		return 1;
	}*/
	SLMerBla(ps);//内存保证足够
	ps->arr[ps->size++] = x;
}


//5.往顺序表头部插入一个元素 (函数定义)
void SLPushFront(SL* ps, SLDatatype x)
{
	assert(ps);
	SLMerBla(ps);
	for (int i = ps->size;i > 0;i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[0] = x;
	ps->size++;
}


//6.删除顺序表尾部的一个元素 (函数定义)
void SLPopBack(SL* ps)
{
	assert(ps);
	assert(ps->size);

	//ps->arr[ps->size - 1] = -1;//多余了
	ps->size--;
}


//7.删除顺序表头部的一个元素 (函数定义)
void SLPopFront(SL* ps)
{
	assert(ps);
	assert(ps->size);
	for (int i = 0;i < ps->size - 1;i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	ps->size--;
}


//8.在指定位置前插入一个元素数据 (函数定义)
void SLInsert(SL* ps, SLDatatype x, int pos)//数据x最后是插到了指定的pos角标
{
	
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);
	SLMerBla(ps);
	for (int i = ps->size;i > pos;i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[pos] = x;
	ps->size++;
}


//9.在指定位置删除一个数据 (函数定义)
void SLErase(SL* ps, int pos)
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);
	for (int i = pos;i < ps->size - 1;i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	ps->size--;
}






//10.查找数据 (函数定义)
void SLFind(SL* ps, SLDatatype x)
{
	for (int i = 0;i < ps->size;i++)
	{
		if (ps->arr[i] == x)
		{
			return i;
		}
	}
	return -1;
}
//11.打印 (函数定义)
void SLprintf(SL* ps)
{
	assert(ps);
	for (int i = 0;i < ps->size;i++)
	{
		printf("%d ", ps->arr[i]);
	}
	printf("\n");
}